#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=2e5+5;
int fa[N],deep[N],si[N],hson[N],top[N],dfn[N],rk[N],w[N],cnt=0;
vector<int> adj[N];

struct Info{
    int max = 0;
    int max1=0;
    Info(int x_ = -0x3f3f3f3f,int y_ = 0):max(x_),max1(y_){}
};

Info operator+(const Info &a,const Info &b){
    return {
        std::max(a.max,b.max), 
        a.max1+b.max1
    };
}

template<typename T>
struct SegmentTree{
    int n;
    vector<T> tag;
    vector<Info> info;
    SegmentTree(int n_) : n(n_), tag(4 * n), info(4 * n) {}

    void pull(int p) {
        info[p] = info[2 * p] + info[2 * p + 1];
    }

    void add(int p, T v, int l, int r) {
        tag[p] += v;
        info[p].max += v * (r - l);
        info[p].max1 += v * (r - l);
    }

    void push(int p, int l, int r) {
        int m = (l + r) / 2;
        add(2 * p, tag[p], l, m);
        add(2 * p + 1, tag[p], m, r);
        tag[p] = 0;
    }

    Info query(int p, int l, int r, int x, int y) {
        if (l >= y || r <= x) {
            return {-0x3f3f3f3f,0};
        }
        if (l >= x && r <= y) {
            return info[p];
        }
        int m = (l + r) / 2;
        push(p, l, r);
        return query(2 * p, l, m, x, y) + query(2 * p + 1, m, r, x, y);
    }

    Info query(int x, int y) {
        return query(1, 0, n, x, y);
    }

    void rangeAdd(int p, int l, int r, int x, int y, T v) {
        if (l >= y || r <= x) {
            return;
        }
        if (l >= x && r <= y) {
            return add(p, v, l, r);
        }
        int m = (l + r) / 2;
        push(p, l, r);
        rangeAdd(2 * p, l, m, x, y, v);
        rangeAdd(2 * p + 1, m, r, x, y, v);
        pull(p);
    }
    
    void rangeAdd(int x, int y, T v) {
        rangeAdd(1, 0, n, x, y, v);
    }

    void modify(int p, int l, int r, int x, const Info &v) {
        if (r - l == 1) {
            info[p] = v;
            return;
        }
        int m = (l + r) / 2;
        push(p, l, r);
        if (x < m) {
            modify(2 * p, l, m, x, v);
        } else {
            modify(2 * p + 1, m, r, x, v);
        }
        pull(p);
    }

    void modify(int x, const Info &v) {
        modify(1, 0, n, x, v);
    }
};

SegmentTree<int> seg(N+5);


int dfs1(int u,int dep){
    hson[u]=-1;
    deep[u]=dep;
    si[u]=1;
    for(int i=0;i<adj[u].size();i++){
        if(adj[u][i]==fa[u])continue;
        fa[adj[u][i]]=u;
        si[u]+=dfs1(adj[u][i],dep+1);
        if(hson[u]==-1||si[adj[u][i]]>si[hson[u]]){
            hson[u]=adj[u][i];
        }
    }
    return si[u];
}

void dfs2(int u,int t){
    top[u]=t;
    dfn[u]=++cnt;
    rk[cnt]=u;
    seg.modify(cnt,{w[u],w[u]});
    if(hson[u]!=-1){
        dfs2(hson[u],t);
    }
    for(int i=0;i<adj[u].size();i++){
        if(adj[u][i]!=hson[u]&&adj[u][i]!=fa[u])dfs2(adj[u][i],adj[u][i]);
    }
}

int lca(int u,int v){
    while(top[u]!=top[v]){
        if(deep[top[u]]>deep[top[v]]){
            u=fa[top[u]];
        }else{
            v=fa[top[v]];
        }
    }
    return deep[u]>deep[v]?v:u;
}

int qmax(int u,int v){
    int res=-0x3f3f3f3f;
    while(top[u]!=top[v]){
        if(deep[top[v]]>deep[top[u]]){
            swap(u,v);
        }
        res=max(res,seg.query(dfn[top[u]],dfn[u]+1).max);
        u=fa[top[u]];
    }
    if(deep[v]>deep[u]){
        swap(u,v);
    }
    res=max(res,seg.query(dfn[v],dfn[u]+1).max);
    return res;
}

int qsum(int u,int v){
    int res=0;
    while(top[u]!=top[v]){
        if(deep[top[v]]>deep[top[u]]){
            swap(u,v);
        }
        res+=seg.query(dfn[top[u]],dfn[u]+1).max1;
        u=fa[top[u]];
    }
    if(deep[v]>deep[u]){
        swap(u,v);
    }
    res+=seg.query(dfn[v],dfn[u]+1).max1;
    return res;
}


void solve(){
    int n,m,s;
    cin>>n;
    for(int i=0;i<n-1;i++){
        int u,v;
        cin>>u>>v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for(int i=1;i<=n;i++){
        cin>>w[i];
    }
    dfs1(1,0);
    dfs2(1,1);

    // cout<<lca(3,4)<<'\n';

    // for(int i=1;i<=n;i++){
    //     cout<<seg.query(i,i+1).max<<' ';
    // }
    // cout<<'\n';
    cin>>m;
    while(m--){
        string s;
        int u,v;
        cin>>s>>u>>v;
        if(s=="CHANGE"){
            seg.modify(dfn[u],{v,v});
            // for(int i=1;i<=n;i++){
            //     cout<<seg.query(i,i+1).max<<' ';
            // }
            // cout<<'\n';
        }else if(s=="QMAX"){
            cout<<qmax(u,v)<<'\n';
        }else{
            cout<<qsum(u,v)<<'\n';
        }
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int t=1;
    // cin>>t;
    while(t--){
        solve();
    }
    return 0;
}